﻿using ORM.Enum;
using ORM.Exception;
using ORM.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ORM.DB
{
    public class DBHelper
    {
        private string DefaultConnectStringName = "Base_ConnectionString";
        private string ConnectStringName { set; get; }
        private string ConnectString { set; get; }
        private DBType ConnectType { set; get; }
        private DBManage _DBManage = new DBManage();
        public DBHelper()
        {
            this.ConnectStringName = DefaultConnectStringName;
            if (System.Configuration.ConfigurationManager.ConnectionStrings[this.ConnectStringName] == null)
            {
                throw new ConnectStringNotExistException();
            }
            else
            {
                this.ConnectString = System.Configuration.ConfigurationManager.ConnectionStrings[this.ConnectStringName].ConnectionString;
                this.ConnectType = _DBManage.GetDBType(this.ConnectStringName);
            }

        }
        public DBHelper(string ConnectStringName)
        {
            this.ConnectStringName = ConnectStringName;
            if (System.Configuration.ConfigurationManager.ConnectionStrings[this.ConnectStringName] == null)
            {
                throw new ConnectStringNotExistException();
            }
            else
            {
                this.ConnectString = System.Configuration.ConfigurationManager.ConnectionStrings[this.ConnectStringName].ConnectionString;
                this.ConnectType = _DBManage.GetDBType(this.ConnectStringName);
            }

        }
        public DbConnection GetConnection()
        {
            return _DBManage.GetDBConn(ConnectString, ConnectType);
        }
        public DataTable ExecuteQuery(string SQL, List<Param> Params)
        {
            DataSet ds = new DataSet();
            using (DbConnection conn = _DBManage.GetDBConn(ConnectString, ConnectType))
            {
                conn.Open();
                DbCommand cmd = _DBManage.GetDBCommand(conn, SQL, ConnectType);
                if (Params != null)
                {
                    foreach (Param item in Params)
                    {
                        _DBManage.AddParmas(cmd, item, ConnectType);
                    }
                }

                DbDataAdapter adapter = _DBManage.GetDBAdapter(cmd, ConnectType);
                adapter.Fill(ds);
            }
            return ds.Tables[0];
        }
        public int ExecuteSQL(string SQL, List<Param> Params)
        {
            //Console.WriteLine("事务线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());
            int executerowcount = 0;
            using (DbConnection conn = _DBManage.GetDBConn(ConnectString, ConnectType))
            {
                conn.Open();
                DbCommand cmd = _DBManage.GetDBCommand(conn, SQL, ConnectType);
                if (Params != null)
                {
                    foreach (Param item in Params)
                    {
                        _DBManage.AddParmas(cmd, item, ConnectType);
                    }
                }
                executerowcount = cmd.ExecuteNonQuery();
            }
            return executerowcount;
        }
        public int ExecuteSQL(DbTransaction Transaction, string SQL, List<Param> Params)
        {
            //Console.WriteLine("事务线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());
            int executerowcount = 0;
            //如果传递了Transition但是连接状态为关闭，说明在事务代码块执行完毕后
            //Transaction还未被GC，所以这里判断一下，防止阻止后续的操作
            if (Transaction.Connection.State == ConnectionState.Open)
            {
                DbCommand cmd = _DBManage.GetDBCommand(Transaction.Connection, SQL, ConnectType);
                cmd.Transaction = Transaction;
                if (Params != null)
                {
                    foreach (Param item in Params)
                    {
                        _DBManage.AddParmas(cmd, item, ConnectType);
                    }
                }
                executerowcount = cmd.ExecuteNonQuery();
            }
            else
            {
                executerowcount = ExecuteSQL(SQL, Params);
            }
            return executerowcount;

        }
        public Object ExecuteScar(string SQL, List<Param> Params)
        {
            Object result = null;
            using (DbConnection conn = _DBManage.GetDBConn(ConnectString, ConnectType))
            {
                conn.Open();
                DbCommand cmd = _DBManage.GetDBCommand(conn, SQL, ConnectType);
                if (Params != null)
                {
                    foreach (Param item in Params)
                    {
                        _DBManage.AddParmas(cmd, item, ConnectType);
                    }
                }
                result = cmd.ExecuteScalar();
            }
            return result;
        }


    }
}
